package com.geniusk.security.Interceptor;

import cn.hutool.core.util.StrUtil;
import com.geniusk.common.enums.ResponseType;
import com.geniusk.common.exception.GraceException;
import com.geniusk.security.core.LoginUser;
import com.geniusk.security.constant.SecurityConstants;
import com.geniusk.security.utils.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

@Slf4j
@Component
public class HeaderInterceptor implements HandlerInterceptor {

    @Autowired
    private TokenUtil tokenUtil;

    /**
     * ThreadLocal可以在同一个线程内共享数据
     * 如：Interceptor --> 控制器Controller --> 业务层Service --> 数据层Mapper(dao)
     */
    public static ThreadLocal<LoginUser> currentUser = new ThreadLocal<>();

    @Override
    public boolean preHandle(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) throws Exception {

        String token = request.getHeader(SecurityConstants.HEADER_AUTH);
        if (StrUtil.isNotBlank(token)) {
            token = URLDecoder.decode(token, StandardCharsets.UTF_8.toString());
            LoginUser loginUser = tokenUtil.getLoginUserByToken(token);
            if (loginUser != null) {
                tokenUtil.verifyToken(loginUser);
                currentUser.set(loginUser);
            }else {
                GraceException.display(ResponseType.FORBIDDEN);
            }
        }else {
            GraceException.display(ResponseType.FORBIDDEN);
        }
        return true;
    }

    @Override
    public void postHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler, Exception ex) throws Exception {
        currentUser.remove();
    }
}